package cn.mulanbay.job.persistent.service;

import cn.mulanbay.common.bean.PageSearch;
import cn.mulanbay.common.util.StringUtil;
import cn.mulanbay.persistent.entity.DatabaseClean;
import cn.mulanbay.persistent.enums.CleanType;
import cn.mulanbay.persistent.mapper.DatabaseCleanMapper;
import cn.mulanbay.persistent.query.QueryBuilder;
import com.baomidou.dynamic.datasource.toolkit.DynamicDataSourceContextHolder;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.List;

@Service
public class DatabaseCleanService extends ServiceImpl<DatabaseCleanMapper, DatabaseClean> {

    /**
     * 调度服务器的数据源名称
     */
    @Value("${schedule.dsName:master}")
    private String scheduleDsName;

    @Autowired
    DatabaseCleanMapper databaseCleanMapper;

    /**
     * 获取列表
     *
     * @param us
     * @return
     */
    public Page<DatabaseClean> getDataList(PageSearch us){
        Page<DatabaseClean> pp = new Page<>(us.getPage(),us.getPageSize(),us.isNeedTotal());
        QueryWrapper qw = QueryBuilder.build(us);
        pp.addOrder(OrderItem.desc("order_index"));
        pp = baseMapper.selectPage(pp,qw);
        return pp;
    }

    /**
     * 获取最大记录数
     *
     * @return
     */
    public long getCounts(DatabaseClean dc) {
        return databaseCleanMapper.getCounts(dc.getTableName());
    }

    /**
     * 清空数据库表
     *
     * @return
     */
    public void truncateTable(DatabaseClean dc) {
        databaseCleanMapper.truncateTable(dc.getTableName());
    }

    /**
     * 获取有效的数据库清理列表
     *
     * @return
     */
    public List<DatabaseClean> getActiveDatabaseClean() {
       return databaseCleanMapper.getActiveList();
    }

    /**
     * 执行数据库清理
     *
     * @param dc
     */
    public void updateAndExecDatabaseClean(DatabaseClean dc) {
        long n = 0L;
        if (dc.getCleanType() == CleanType.TRUNCATE) {
            this.changeDataSource(dc.getDsName());
            this.truncateTable(dc);
        } else {
            LocalDateTime date = LocalDateTime.now().minusDays(dc.getDays());
            this.changeDataSource(dc.getDsName());
            n = databaseCleanMapper.deleteData(dc.getTableName(),dc.getDateField(),date,genExtraCondition(dc.getExtraCondition()));
        }
        //需要切换到主数据源
        this.changeDataSource(null);
        //更新
        dc.setLastCleanCounts(n);
        dc.setLastCleanTime(LocalDateTime.now());
        databaseCleanMapper.updateById(dc);
    }

    private String genExtraCondition(String s){
        if(StringUtil.isNotEmpty(s)){
            return "and "+s;
        }else{
            return "";
        }
    }
    /**
     * 手动执行数据库清理
     *
     * @param dc
     */
    public long manualClean(DatabaseClean dc, int days, boolean updateConfig) {
        LocalDateTime date = LocalDateTime.now().minusDays(days);
        //切换数据源
        this.changeDataSource(dc.getDsName());
        long n = databaseCleanMapper.deleteData(dc.getTableName(),dc.getDateField(),date,genExtraCondition(dc.getExtraCondition()));
        //需要切换到主数据源
        this.changeDataSource(null);
        //更新
        if (updateConfig) {
            dc.setLastCleanCounts(n);
            dc.setLastCleanTime(LocalDateTime.now());
            databaseCleanMapper.updateById(dc);
        }
        return n;
    }

    /**
     * 切换数据源
     * @param dsName
     */
    private void changeDataSource(String dsName){
        if(StringUtil.isNotEmpty(dsName)){
            DynamicDataSourceContextHolder.push(dsName);
        }else{
            DynamicDataSourceContextHolder.push(scheduleDsName);
        }
    }

}
